//转时间
import { count } from './mathjs.ts';

//储存缓存
export const setItem = (keyName: string, value: any) => {
  if (typeof value === 'string') {
    return localStorage.setItem(keyName, value);
  } else {
    return localStorage.setItem(keyName, JSON.stringify(value));
  }
};
//获取缓存
export const getItem = (keyName: string) => {
  let _value: any = localStorage.getItem(keyName);
  if (needsJSONParse(_value)) {
    return JSON.parse(_value);
  } else {
    return _value || '';
  }
};
//清除缓存
export const removeItem = (keyName: string) => {
  localStorage.removeItem(keyName);
};
//已知总宽度 totalWidth 和最小列宽 minColumnWidth，计算最多可以显示多少列，并且返回的列数要是 2 的倍数。
export const getEvenColumnCount = (totalWidth: number, minColumnWidth: number, multiple: number = 1) => {
  const maxColumns = Math.floor(totalWidth / minColumnWidth); // 最大列数（整数）
  if (maxColumns <= 0) return 0;
  // 向下取整到最近的 2 的倍数
  const evenColumns = Math.floor(maxColumns / multiple) * multiple;

  return evenColumns;
};
//窗口变化防抖
export const useResize = (callback: Function, delay: number = 100) => {
  const resizeTimeout: any = ref(null);
  function onWindowResize() {
    if (resizeTimeout.value) {
      clearTimeout(resizeTimeout.value);
    }
    resizeTimeout.value = setTimeout(() => {
      callback();
    }, delay);
  }
  onMounted(() => {
    nextTick(() => {
      callback();
    });
    window.addEventListener('resize', onWindowResize);
  });
  onUnmounted(() => {
    if (resizeTimeout.value) {
      clearTimeout(resizeTimeout.value);
    }
    window.removeEventListener('resize', onWindowResize);
  });
};
//排序
export const sortArr = (arr: any, key: string | Function) => {
  arr.sort((a: any, b: any) => (typeof key === 'function' ? key() : a[key] - b[key]));
};
//判断数组是否有多条满足
export const hasMultipleMatches = (arr: any, conditionFn: Function, number: number = 1) => {
  // 使用filter获取所有满足条件的元素
  const matches = arr.filter(conditionFn);
  // 如果匹配的元素数量大于1，则返回true，否则false
  return matches.length > number;
};
//判断是否符合JSONParse
export const needsJSONParse = (data: any) => {
  if (typeof data === 'string') {
    try {
      // 尝试解析 JSON 字符串
      const parsedData = JSON.parse(data);
      return true;
    } catch (e) {
      // 如果解析失败，说明这不是一个有效的 JSON 字符串
      return false;
    }
  }
  // 如果数据不是字符串，则不需要解析
  return false;
};
//金钱格式
export const money = (value: string = '', precision: number = 2) => {
  return value ? `￥${Number(value).toFixed(precision)}` : '￥0.00';
};
//转换尺寸
export const size = (size: number | string, sizeDefault: string = '120px') => {
  return typeof size === 'number' ? `${size}px` : size || sizeDefault;
};
//mm转px
export const mmToPx = (mm: number) => {
  const ppi = 96; // 默认PPI
  const px = mm * (ppi / 25.4);
  return Number(px.toFixed(0));
};
//数字转大写
export const chineseNumber = (amount: number) => {
  var cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']; // Chinese numerals
  var cnIntRadice = ['', '拾', '佰', '仟']; // Integer level (for 10, 100, 1000)
  var cnIntUnits = ['', '万', '亿', '兆']; // Integer unit
  var cnDecUnits = ['角', '分']; // Decimal unit
  var cnInteger = '元'; // Integer base unit
  var cnZero = '零'; // Zero
  var cnMaxNum = 999999999999.99; // Maximum value

  if (amount >= cnMaxNum) {
    console.error('超出最大处理数值');
    return '超出最大处理数值';
  }

  if (amount == 0) {
    return cnZero + cnInteger + cnZero;
  }

  var integerPart = Math.floor(amount); // Get the integer part
  var decimalPart = Math.round((amount - integerPart) * 100); // Get the decimal part and round it

  var parts = [];
  if (integerPart > 0) {
    var zeroCount = 0;
    var intLen = integerPart.toString().length;
    for (var i = 0; i < intLen; i++) {
      var n = integerPart.toString()[i];
      var p = intLen - i - 1;
      var q = Math.floor(p / 4);
      var m = p % 4;
      if (n == '0') {
        zeroCount++;
      } else {
        if (zeroCount > 0) {
          parts.push(cnZero);
          zeroCount = 0;
        }
        parts.push(cnNums[parseInt(n)] + cnIntRadice[m]);
      }
      if (m == 0 && zeroCount < 4) parts.push(cnIntUnits[q]);
    }
    parts.push(cnInteger);
  }

  if (decimalPart > 0) {
    var decStr: any = decimalPart.toString();
    for (var i = 0; i < cnDecUnits.length; i++) {
      if (i < decStr.length) {
        parts.push(cnNums[decStr[i]] + cnDecUnits[i]);
      }
    }
  } else {
    parts.push('整');
  }

  return parts.join('');
};
//文本高亮
export const highlightedText = (text: string, highlightWords: string | any[], color: string = '#3f61f1') => {
  let result = text;
  let _highlightWords: any[] = Array.isArray(highlightWords) ? highlightWords : [highlightWords];
  _highlightWords.forEach((word: any) => {
    const regExp = new RegExp(`(${word})`, 'gi'); // 创建正则表达式，忽略大小写
    result = result.replace(regExp, `<span style="color: ${color};">$1</span>`);
  });
  return result;
};

//提示
export const openUrl = (url: string) => {
  window.open(url, '_blank');
};
//提示
export const message = (name: any = '操作成功', type: any = 'success', showClose: any = false) => {
  ElMessage({
    showClose: showClose,
    message: name,
    type: type,
  });
};
//询问
export const messageBox = (message: any = '操作成功', fun: any, type?: string) => {
  ElMessageBox.confirm(message, '消息', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: type,
  }).then(() => {
    if (!fun) return;
    fun();
  });
};
//询问+原因
export const messageInputBox = (
  message: any = '操作成功',
  fun: any,
  input: any = {
    inputPattern: '',
    inputErrorMessage: '',
    inputPlaceholder: '请输入',
  },
  type?: string,
) => {
  ElMessageBox.prompt('', message, {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    inputPattern: input.inputPattern,
    inputErrorMessage: input.inputErrorMessage,
    inputPlaceholder: input.inputPlaceholder,
    inputValidator: (value) => {
      if (!value) {
        return '请输入内容';
      }
      return true;
    },
    type: type,
  }).then(({ value }) => {
    fun(value);
  });
};
//是否是方法
export const isFunction = (fun: Function) => {
  return fun && typeof fun === 'function';
};
//复制
export const copy = (text: string, isState: boolean = true, message: string = '复制成功') => {
  if (text) {
    // 获取要复制的文本
    let textToCopy = text;
    // 创建一个隐藏的textarea元素
    let textarea = document.createElement('textarea');
    // 将文本设置为textarea的值
    textarea.value = textToCopy;
    // 将textarea添加到页面中
    document.body.appendChild(textarea);
    // 选中textarea中的文本
    textarea.select();
    // 复制选中的文本到剪贴板
    document.execCommand('copy');
    // 从页面中移除textarea元素
    document.body.removeChild(textarea);
    if (isState) {
      ElMessage({
        showClose: false,
        message: message,
        type: 'success',
      });
    }
  }
};
//还原信息
export const decodeHtmlEntities = (htmlString: string) => {
  // 创建一个临时的DOM元素
  const tempElement = document.createElement('textarea');
  tempElement.innerHTML = htmlString;
  // 返回解码后的文本
  return tempElement.value;
};
//清除html标签信息
export const stripHtmlTags = (htmlString: string) => {
  // 解码HTML实体
  const decodedString = decodeHtmlEntities(htmlString);

  // 创建一个新的DOMParser实例
  const parser = new DOMParser();
  // 解析字符串为一个Document对象
  const doc = parser.parseFromString(decodedString, 'text/html');
  // 返回document.body中的文本内容，这会自动去除所有HTML标签
  return doc.body.textContent || '';
};
//英文字母全部大写
export const toUpperCase = (string: string) => {
  return string.toUpperCase();
};
//英文字母全部小写
export const toLowerCase = (string: string) => {
  return string.toLowerCase();
};
//英文字母小驼峰
export const toCamelCase = (string: string) => {
  return (
    string
      // 将下划线和连字符替换为空格以便统一处理
      .replace(/[_-]/g, ' ')
      // 将字符串分割成单词数组
      .split(' ')
      // 将单词数组转换为小驼峰形式
      .map((word, index) => (index === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()))
      // 将数组重新组合成字符串
      .join('')
  );
};
//英文字母大驼峰
export const toPascalCase = (string: string) => {
  return (
    string
      // 将下划线和连字符替换为空格以便统一处理
      .replace(/[_\s-]+/g, ' ')
      // 将字符串分割成单词数组
      .split(' ')
      // 将单词数组转换为大驼峰形式
      .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
      // 将数组重新组合成字符串
      .join('')
  );
};
//千位分隔符 输出: 123,456
export const toLocaleString = (number: number) => {
  let _number: number = Number(number.toFixed(2));
  return _number.toLocaleString('en-US'); // 使用美国英语区域设置，会自动加上千位分隔符
};
//相差天数
export const daysDifference = (inputDate: any, today: any = new Date()) => {
  // 如果输入的是字符串，则将其转换为 Date 对象
  let date;
  if (!inputDate) {
    return {
      dayDiff: 0,
      dayDiffText: '未知',
    };
  }
  if (typeof inputDate === 'string') {
    date = new Date(inputDate);
  } else if (inputDate instanceof Date) {
    date = new Date(inputDate.getTime()); // 创建一个新的 Date 实例以避免修改原始对象
  } else {
    throw new Error('inputDate必须是Date对象或有效的日期字符串');
  }
  // 获取今天的日期，不包含当前时间（即设为00:00:00）
  today.setHours(0, 0, 0, 0);
  // 计算两个日期之间的时间差（以毫秒为单位）
  const timeDiff = date.getTime() - today.getTime();

  // 相差天数
  const dayDiff = Math.round(timeDiff / (1000 * 3600 * 24));
  //相差天数描述
  const dayDiffText = dayDiff >= 0 ? `还剩 ${dayDiff} 天` : `超期 ${-dayDiff} 天`;
  return {
    dayDiff,
    dayDiffText,
  };
};
//相差天数
export const getYearDifference = (startDate: any, endDate: any = new Date()) => {
  // 将输入的日期字符串或Date对象转换为Date对象
  const start = new Date(startDate);
  const end = new Date(endDate);

  // 计算年份差
  let yearDiff = end.getFullYear() - start.getFullYear();

  // 调整年份差：如果结束日期还没到开始日期的月份和日子，则减去一年
  const monthDifference = end.getMonth() - start.getMonth();
  if (monthDifference < 0 || (monthDifference === 0 && end.getDate() < start.getDate())) {
    yearDiff--;
  }

  return yearDiff;
};
//判断是否是数组
export const isArr = (arr: any) => {
  return arr && Array.isArray(arr);
};
//数组求和/均价
export const arrTotal = (arr: any, key: string, isAverage: boolean = false, fun?: Function) => {
  let _number = 0;
  if (isArr(arr)) {
    _number = arr.reduce((number: number, item: any) => {
      const _number = key ? item[key] : item;
      if (_number && (!fun || fun(item))) {
        return count(`${number}+${_number}`, 9);
      } else {
        return number;
      }
    }, 0);
  }
  return isAverage ? count(`${_number}/${arr.length}`, 9) : _number;
};
//过滤新的数组
export const filterArr = (arr: any, isFun: Function) => {
  if (isArr(arr)) {
    return arr.reduce((arr: any, item: any) => {
      if (!isFun || isFun(item)) {
        return arr.concat([item]);
      } else {
        return arr;
      }
    }, []);
  } else {
    return [];
  }
};
//数组find
export const arrFind = (arr: any, value: any, valueName: string = 'value', labelName?: string) => {
  let _obj: any = {
    label: '',
    value: value,
  };
  if (arr?.length > 0) {
    _obj = arr.find((el: any) => el[valueName] === value);
  }
  if (labelName) {
    return _obj ? _obj[labelName] : value;
  } else {
    return _obj || value;
  }
};
//对象数组的平铺（扁平化）
export const flattenObjectArray = (array: any, childName: string, fun?: Function) => {
  return array.reduce((arr: any, item: any, elIndex: number) => {
    if (item[childName]?.length > 0) {
      const newArr = item[childName].map((el: any, chilchIndex: number) => {
        const _row = {
          ...item,
          ...el,
          rowspan: chilchIndex === 0 ? item[childName].length : 0,
          rowClass: elIndex % 2 ? 'primary-row' : '',
        };
        if (typeof fun === 'function') {
          return fun(_row);
        } else {
          return _row;
        }
      });
      return arr.concat(newArr);
    } else {
      return arr;
    }
  }, []);
};
//新老数据转换
export const ObjToObj = (rowTo: any, rowFrom: any, rowKey?: any) => {
  if (rowTo && typeof rowTo === 'object' && rowTo && typeof rowTo === 'object') {
    if (rowKey && typeof rowKey === 'object') {
      for (const key in rowKey) {
        rowFrom[rowKey[key]] = rowTo[key];
      }
    } else {
      for (const key in rowTo) {
        rowTo[key] = rowFrom[key];
      }
    }
  }
};
//获取新数据
export const getNewObj = (row: any, rowKey: any) => {
  let _obj: any = {};
  if (row && typeof row === 'object' && rowKey && typeof rowKey === 'object') {
    for (const key in rowKey) {
      _obj[rowKey[key]] = row[key];
    }
  }
  return _obj;
};
//点击/双击判断逻辑
let clickCount = 0;
export const clickOrDoubleClick = (singleClickCallback: Function = () => {}, doubleClickCallback: Function = () => {}, delay: number = 300) => {
  clickCount++;
  if (clickCount === 1) {
    setTimeout(() => {
      if (clickCount === 1) {
        console.log('单击');
        // 单击处理
        singleClickCallback(event);
      } else {
        console.log('双击');
        // 双击处理
        doubleClickCallback(event);
      }
      clickCount = 0; // 重置点击计数
    }, delay);
  }
};
//下载文件
export const downloadUrl = (url: string, filename: string) => {
  const a = document.createElement('a');
  a.href = url;
  a.download = filename || 'download'; // 指定下载的文件名
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
};
//预览文件
export const previewContent = (url: string, filename: string) => {};
//判断嵌套对象中是否存在某个值（深度查找）
export const deepHasValue = (obj: any, target: string): boolean => {
  return Object.values(obj).some((value: any) => {
    if (value && typeof value === 'object') {
      return deepHasValue(value, target);
    }
    return value === target;
  });
};
//判断嵌套对象中进行初始化（深度查找）
export const initializeAtPath = (obj: any, pathKeys: any[]): object => {
  if (typeof obj !== 'object' || obj === null) return obj;
  const result: any = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    if (!obj.hasOwnProperty(key)) continue;

    const value = obj[key];
    const shouldInitialize = pathKeys.includes(key);

    if (shouldInitialize) {
      // 根据原始值类型进行初始化
      if (typeof value === 'string') {
        result[key] = '';
      } else if (typeof value === 'number') {
        result[key] = null;
      } else if (typeof value === 'boolean') {
        result[key] = false;
      } else if (Array.isArray(value)) {
        result[key] = [];
      } else if (typeof value === 'object' && value !== null) {
        result[key] = {}; // 对于对象，我们在这里先设为{}，之后会递归处理
      } else {
        result[key] = undefined; // 或者保留原值：value
      }
    } else if (typeof value === 'object' && value !== null) {
      // 如果不是要初始化的key且是对象或数组，则递归处理
      result[key] = initializeAtPath(value, pathKeys);
    } else {
      result[key] = value;
    }
  }

  return result;
};
